#pragma once

#include <iostream>
#include <string>
#include <cstdarg>
#include <ctime>
#include <sys/types.h>
#include <unistd.h>

using namespace std;


#define LOG_NORMAL "log.txt"
#define DEBUG 0
#define NORMAL 1

#define LOG_ERR "log.error"
#define WARNING 2
#define ERROR 3
#define FATAL 4

const char* to_levelStr(int level)
{
    switch(level)
    {
        case DEBUG: return "DEBUG";
        case NORMAL: return "NORMAL";
        case WARNING: return "WARNING";
        case ERROR: return "ERROR";
        case FATAL: return "FATAL";
        default : return nullptr;
    }
}

// logMessage(DEBUG, "hello %f, %d, %c", 3.14, 10, 'C');
void logMessage(int level, const char *format, ...)
{
    // [日志等级] [时间戳/时间] [pid] [message]
    // [WARNING] [2023-5-30 9:05:03] [123] [create socket error]

    // va_list start; // va_list是char*类型的指针
    // va_start(start, format);
    // while (*start)
    // {
    //     va_arg(start, float); // 让指针向后移动指定类型的大小
    // }
    // va_end(start); // 让start指针变为nullptr

#define NUM 1024
//日志的前缀内容
    char logprefix[NUM];
    snprintf(logprefix, sizeof(logprefix), "[%s] [%ld] [pid:%d]", to_levelStr(level), (long int)time(nullptr), getpid()); //gettimeofday() localtime()
//日志的格式化内容
    char logcontent[NUM]; 
    va_list arg;
    va_start(arg, format);//参数压栈顺序是从右向左的, 指针起始地址指向从左向右第一个参数, 栈先使用高地址再使用低地址,所以使用时栈顶指针会减减
    vsnprintf(logcontent, sizeof(logcontent), format, arg);

    // cout << logprefix << logcontent << endl;

    //改成文件版本
    FILE *log = fopen(LOG_NORMAL, "a");
    FILE *err = fopen(LOG_ERR, "a");
    if(log != nullptr && err != nullptr)
    {
        // 两个文件打开成功之后 向两个文件进行写入
        if(level == DEBUG || level == NORMAL || level == WARNING)
        {
            fprintf(log, "%s%s\n", logprefix, logcontent);
        }
        else
        {
            fprintf(err, "%s%s\n", logprefix, logcontent);
        }
        
        fclose(log);
        fclose(err);
    }
}
